/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.isip.chaincode;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

/**
 *
 * @author Ahmad Fauzan
 */
public class ChainCode {
    String chaincode;
    int x,y;
    boolean isAdvance = false;
    String name = "";
    
    public ChainCode(int x, int y, String chainCode) {
        this.x = x;
        this.y = y;
        this.chaincode = chainCode;
    }
    
    public ChainCode(String name , int x, int y, String chainCode, boolean isModel) {
        this.x = x;
        this.y = y;
        this.chaincode = chainCode;
        isAdvance = isModel;
        this.name = name;
    }
    
    public String getSequence() {
        String clean_chaincode = cleanChainCode();
        
        String sequence = "" + clean_chaincode.charAt(0);
        for (int i = 1; i < clean_chaincode.length(); i++) {
            if (sequence.charAt(sequence.length() - 1) != clean_chaincode.charAt(i)) {
                sequence += clean_chaincode.charAt(i);
            }
        }
       
        return sequence;
    }
    
    public String cleanChainCode() {
        int threshold = chaincode.length()/50;
        String sequence = "";
        for (int i = 1; i < chaincode.length(); i++) {
            String temp = ""+chaincode.charAt(i-1);
            while(i < chaincode.length() && chaincode.charAt(i) == chaincode.charAt(i-1)) {
                temp += chaincode.charAt(i);
                i++;
            }
            if(temp.length() < threshold) {
                sequence += temp.charAt(0);
            } else {
                sequence += temp;
            }
        }
       
        return sequence;
    }
    
    static String cleanDuplicate(String input) {
        String sequence = "" + input.charAt(0);
        for (int i = 1; i < input.length(); i++) {
            if (sequence.charAt(sequence.length() - 1) != input.charAt(i)) {
                sequence += input.charAt(i);
            }
        }
       
        return sequence;
    }
    
    public String getAdvanceSequence() {
        
        if(isAdvance) return chaincode;
        
        String sequence = cleanChainCode();
        
        String sequenceDir = "147896321";
        char c = 'a';
        for(int i=0; i < sequenceDir.length()-1; i++) {
            String  temp = sequenceDir.substring(i, i+2);
            sequence = sequence.replace(sequenceDir.substring(i, i+2), ""+c);
            sequence = sequence.replace("" + c + temp.charAt(0), ""+c);
            sequence = sequence.replace("" + temp.charAt(0) + c, ""+c);
            sequence = sequence.replace(""+ c + temp.charAt(1), ""+c);
            sequence = sequence.replace(""+temp.charAt(1)+c, ""+c);
            c += 1;
        }
        
        String temp = sequence;
        sequence = "";
        int count = 0;
        for(int i=0; i < temp.length(); i++) {
            char ct = temp.charAt(i);
            while(i < temp.length() && ct == temp.charAt(i)) {
                count++;
                i++;
            }
            if(count > 1) {
                sequence += ct;
                count = 0;
            }
        }
        
        return cleanDuplicate(sequence);
    }
    public String getChaincode() {
        return chaincode;
    }
    
    public float compareWithBase(ChainCode otherModel) {
        return Math.max(same(otherModel.getAdvanceSequence(), this.getAdvanceSequence(),5),same(this.getAdvanceSequence(),otherModel.getAdvanceSequence(),5));
    }
    
    static float same(String baseChainCode, String chaincode, int threshold) {
        float same = 0;
        int p1 =0;
        int p2 = 0;
        int countThreshold = 0;
        for(; p1 < baseChainCode.length();p1++) {
            for(int j = p2; j < chaincode.length(); j++) {
                if(baseChainCode.charAt(p1) == chaincode.charAt(j)) {
                    p2 = j;
                    same += 1;
                    countThreshold = 0;
                    break;
                } else if(countThreshold >= threshold){
                    p2 = j;
                    break;
                } else {
                    countThreshold++;
                }
            }
        }
        return same/Math.max(baseChainCode.length(),chaincode.length());
    } 
    
    public static ChainCode MatchWithModels(ChainCode input, ChainCode[] models) {
        float max;
        int idx = 0;
        max = input.compareWithBase(models[idx]);
        for(int i =1; i < models.length; i++) {
            float temp = input.compareWithBase(models[i]);
            if(max < temp) {
                idx = i;
                max = temp;
            }
        }
        
        return models[idx];
    }
    
    public static ChainCode[] LoadModel() {  
        ChainCode[] temp = new ChainCode[10];
        temp[0] = new ChainCode("1", 0,0, "6842ab2f", true);
        temp[1] = new ChainCode("2", 0,0, "6ed8cbce6842gfg2ha4b2f", true);
        temp[2] = new ChainCode("3", 0,0, "6ed8cbed8cb4a2efgha426fgha4b2f", true);
        temp[3] = new ChainCode("4", 0,0, "68d684b842a42g", true);
        temp[4] = new ChainCode("5", 0,0, "684bce36ed8cb4a2efg2ha4bg", true);
        temp[5] = new ChainCode("6", 0,0, "6e8a4bc9gf6ed8cbah2hg2gf", true);
        temp[6] = new ChainCode("7", 0,0, "68c4ga42", true);
        temp[7] = new ChainCode("8", 0,0, "6ed8cbed8cbahgfah2gf", true);
        temp[8] = new ChainCode("9", 0,0, "6ed8cb4a2efg1cbah2gf", true);
        temp[9] = new ChainCode("0", 0,0, "6ed8cb4ah2gf", true);
        return temp;
    }

    public static ChainCode[] LoadModel(String modelPath) throws FileNotFoundException, IOException {
        String[] data = ReadLines(modelPath);
        ArrayList<ChainCode> tempList = new ArrayList<>();
        for(int i=0; i < data.length; i++) {
            String[] atoms = data[i].split(",");
            for(int j=1; j < atoms.length; j++) {
                ChainCode chaincodemodel = new ChainCode(atoms[0], 0,0,atoms[j], true);
                tempList.add(chaincodemodel);
            }
        }
        
        ChainCode[] temp = new ChainCode[tempList.size()];
        
        for(int i=0; i < temp.length; i++) {
            temp[i] = tempList.get(i);
        }
        
        return temp;
    }
    
    public static String[] ReadLines (String path) throws FileNotFoundException, IOException {
        BufferedReader br = new BufferedReader(new FileReader(path));
        String everything = " ";
        try {
            StringBuilder sb = new StringBuilder();
            String line = br.readLine();

            while (line != null) {
                sb.append(line);
                sb.append("\n");
                line = br.readLine();
            }
            everything = sb.toString();
        } finally {
            br.close();
        }
        String[] w = everything.split("\n");
        return (w);
    }
    
    public String getName() {
        return name;
    }
    
    
}
